package main

import (
	"bufio"
	"crypto/md5"
	"flag"
	"fmt"
	"morego_go_client/protocol"
	"net"
	"net/url"
	"os"
	"strconv"
	"strings"
	"time"
	//"morego_go_client/websocket"
	"github.com/gorilla/websocket"
)

func createReqStrData(num int64) []string {

	var reqs_strs = []string{}
	data := ""
	for i := 0; i < int(num); i++ {
		type_ := protocol.TypeReq
		cmd := "user.getUser"
		req_data := time.Now().Unix()
		srcData := "1" // []byte( strconv.FormatInt(time.Now().Unix(), 10) )
		sid := md5.Sum([]byte(srcData))
		req_id := int32(time.Now().Unix())
		data = fmt.Sprintf("%d||%s||%x||%d||%d", type_, cmd, sid, req_id, req_data)
		reqs_strs = append(reqs_strs, data)
	}
	return reqs_strs

}

func asyncReqStrSplit(datas []string) []*SocketResponse {

	//ch := make( chan *SocketResponse )
	responses := []*SocketResponse{}

	for _, data := range datas {
		go func(data string) {
			//fmt.Printf("Req %s \n", data)
			times, _ := strconv.ParseInt(os.Args[3], 10, 32)
			if len(os.Args) < 2 {
				fmt.Fprintf(os.Stderr, "Usage: %s host:port ", os.Args[0])
				os.Exit(1)
			}
			service := os.Args[1]
			tcpAddr, err := net.ResolveTCPAddr("tcp4", service)
			checkError(err)
			conn, err := net.DialTCP("tcp", nil, tcpAddr)
			//defer conn.Close()
			checkError(err)
			reqWithStr(conn, data, int(times))

		}(data)
	}

	return responses
}

func asyncReqStrSplitWs(datas []string) []*SocketResponse {

	//ch := make( chan *SocketResponse )
	responses := []*SocketResponse{}
	times, _ := strconv.ParseInt(os.Args[3], 10, 32)

	service := os.Args[1]
	var addr = flag.String("addr", service, "http service address")
	for _, data := range datas {
		go func(data string) {

			u := url.URL{Scheme: "ws", Host: *addr, Path: "/"}
			c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
			fmt.Println("connecting to ", service)

			if err != nil {
				fmt.Println("dial:", err)
			}
			defer c.Close()

			reqWithStrWs(c, data, int(times))
		}(data)
	}

	return responses
}

func reqWithStrWs(ws *websocket.Conn, data string, times int) {

	ws.WriteMessage(websocket.TextMessage, []byte(data))
	var i int
	i = 0
	sid := ""

	//var msg = make([]byte, 512)
	for {
		_, buf, err := ws.ReadMessage()

		if err != nil {
			return
		}
		str := string(buf)
		if err != nil {
			fmt.Println("read:", err)
			return
		}

		//fmt.Println("recvice :", str)
		msg_arr := strings.Split(str, "||")
		if len(msg_arr) < 5 {
			fmt.Println("err: response data length error!", msg_arr)
			continue
		} else {
			if len(msg_arr) > 5 {
				for i := 4; i < int(len(msg_arr)); i++ {
					msg_arr[4] = msg_arr[4] + msg_arr[i]
				}
			}
		}

		cmd := msg_arr[1]
		//fmt.Println(" cmd: ", cmd)
		if cmd == "user.getSession" {
			sid = msg_arr[2]
			ws.WriteMessage(websocket.TextMessage, []byte(data))
			i++
			if i > times {
				ws.Close()
				fmt.Println(" sid : ", sid)
				fmt.Println(" conn close! ", i)
				break
			}
		}

	}
	ws.Close()

}

//
func reqWithStr(conn *net.TCPConn, data string, times int) {

	conn.Write(append([]byte(data), '\n'))
	var i int
	i = 0
	sid := ""
	reader := bufio.NewReader(conn)

	for {
		str, err := reader.ReadString('\n')
		if err != nil {
			fmt.Println("err:", err.Error())
			conn.Close()
			break
		}
		//fmt.Println("recvice :", str)
		msg_arr := strings.Split(str, "||")
		if len(msg_arr) < 5 {
			fmt.Println("err: response data length error!", msg_arr)
			continue
		} else {
			if len(msg_arr) > 5 {
				for i := 4; i < int(len(msg_arr)); i++ {
					msg_arr[4] = msg_arr[4] + msg_arr[i]
				}
			}
		}

		cmd := msg_arr[1]
		//fmt.Println(" cmd: ", cmd )
		if cmd == "user.getSession" {
			sid = msg_arr[2]
			conn.Write(append([]byte(data), '\n'))
			i++
			if i > times {
				conn.Close()
				fmt.Println(" sid : ", sid)
				fmt.Println(" conn close! ", i)
				break
			}
		}

	}
	conn.Close()

}
